import pandas as pd  # 导入 pandas 库，用于数据处理和分析
import numpy as np   # 导入 numpy 库，用于数值计算
from sklearn.linear_model import LinearRegression  # 从 sklearn 库中导入线性回归模型
import matplotlib.pyplot as plt  # 导入 matplotlib 库中的 pyplot 模块，用于绘图

# 读取数据
file_path = 'a2.xlsx'  # 设置数据文件路径
sheet_name = 'Sheet1'  # 设置工作表名称

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置使用中文字体（例如：黑体）
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

try:
    df = pd.read_excel(file_path, sheet_name=sheet_name)  # 读取 Excel 文件中的数据到 DataFrame
except FileNotFoundError:
    print(f"Error: 文件 '{file_path}' 未找到.")  # 如果文件未找到，输出错误信息
    exit(1)
except Exception as e:
    print(f"Error: 读取文件 '{file_path}' 时出现异常: {str(e)}")  # 如果出现其他异常，输出错误信息
    exit(1)

# 假设数据包含两列：年份和资产负债率
if '年份' not in df.columns or '资产负债率' not in df.columns:
    print("Error: 数据格式不正确，缺少 '年份' 或 '资产负债率' 列.")  # 如果数据列不符合预期，输出错误信息
    exit(1)

# 排序确保按年份顺序处理
df.sort_values(by='年份', inplace=True)  # 按照 '年份' 列对数据进行排序

# 数据预处理
years = df['年份'].values.reshape(-1, 1)  # 提取 '年份' 列并重塑为二维数组
debt_equity_ratio = df['资产负债率'].values  # 提取 '资产负债率' 列的数值

# 模型训练与预测
try:
    model = LinearRegression()  # 创建线性回归模型的实例
    model.fit(years, debt_equity_ratio)  # 使用数据训练模型

    # 构建未来预测的年份序列
    future_years = np.arange(df['年份'].min(), df['年份'].max() + 10).reshape(-1, 1)  # 构建预测年份序列
    future_predicted_ratios = model.predict(future_years)  # 使用模型预测未来资产负债率

    # 打印预测结果
    print("预测未来10年的资产负债率：")
    for year, ratio in zip(future_years.flatten(), future_predicted_ratios):
        print(f"年份 {year}: 预测资产负债率为 {ratio:.3f}")

    # 结果可视化
    plt.figure(figsize=(10, 6))  # 设置画布大小
    plt.scatter(years, debt_equity_ratio, color='blue', label='实际值')  # 绘制实际值散点图
    plt.plot(future_years, future_predicted_ratios, color='red', linestyle='--', label='预测值')  # 绘制预测值折线图
    plt.title('企业资产负债率预测')  # 设置图表标题
    plt.xlabel('年份')  # 设置x轴标签
    plt.ylabel('资产负债率')  # 设置y轴标签
    plt.ylim(0, 1)  # 设置纵坐标范围为 0 到 1
    plt.legend()  # 显示图例
    plt.grid(True)  # 显示网格线
    plt.show()  # 显示图表
except Exception as e:
    print(f"Error: 模型训练和预测过程中出现异常: {str(e)}")  # 如果模型训练或预测过程中出现异常，输出错误信息

